/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package me.zhengjie.modules.biz.rest;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import me.zhengjie.LogUtils;
import me.zhengjie.annotation.AnonymousAccess;
import me.zhengjie.annotation.Log;
import me.zhengjie.annotation.rest.AnonymousGetMapping;
import me.zhengjie.modules.biz.domain.Cabinet;
import me.zhengjie.modules.biz.repository.CabinetRepository;
import me.zhengjie.modules.biz.service.CabinetService;
import me.zhengjie.modules.biz.service.IncubatorService;
import me.zhengjie.modules.biz.service.dto.CabinetQueryCriteria;
import me.zhengjie.modules.utils.BaseResult;
import me.zhengjie.utils.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Enumeration;
import java.util.Map;
import java.util.Objects;

/**
 * @author Admin
 * @website https://eladmin.vip
 * @date 2023-03-01
 **/
@RestController
@RequiredArgsConstructor
@Api(tags = "cabinet管理")
@RequestMapping("/api/cabinet")
public class CabinetController {

    private final CabinetService cabinetService;
    private final IncubatorService incubatorService;
    private final CabinetRepository cabinetRepository;

    @Log("导出数据")
    @ApiOperation("导出数据")
    @GetMapping(value = "/chemicalsList/download")
//    @PreAuthorize("@el.check('cabinet:list')")
    public void exportCabinet(HttpServletResponse response, CabinetQueryCriteria criteria) throws IOException {
        cabinetService.download(cabinetService.queryAll(criteria), response);
    }

    @GetMapping
    @Log("查询cabinet")
    @ApiOperation("查询cabinet")
    @AnonymousAccess
//    @PreAuthorize("@el.check('cabinet:list')")
    public ResponseEntity<Object> queryCabinet(CabinetQueryCriteria criteria, Pageable pageable) {
        return new ResponseEntity<>(cabinetService.queryAll(criteria, pageable), HttpStatus.OK);
    }

    @PostMapping
    @Log("新增cabinet")
    @ApiOperation("新增cabinet")
//    @PreAuthorize("@el.check('cabinet:add')")
    public ResponseEntity<Object> createCabinet(@Validated @RequestBody Cabinet resources) {
        return new ResponseEntity<>(cabinetService.create(resources), HttpStatus.CREATED);
    }

    @PutMapping
    @Log("修改cabinet")
    @ApiOperation("修改cabinet")
//    @PreAuthorize("@el.check('cabinet:edit')")
    public ResponseEntity<Object> updateCabinet(@Validated @RequestBody Cabinet resources) {
        cabinetService.update(resources);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @DeleteMapping
    @Log("删除cabinet")
    @ApiOperation("删除cabinet")
//    @PreAuthorize("@el.check('cabinet:del')")
    public ResponseEntity<Object> deleteCabinet(@RequestBody Integer[] ids) {
        cabinetService.deleteAll(ids);
        return new ResponseEntity<>(HttpStatus.OK);
    }

    @ApiOperation("查询所有柜子列表")
    @GetMapping("/chemicalsList")
    public ResponseEntity<Object> queryChemicalsList(CabinetQueryCriteria criteria, Pageable pageable) {
        return new ResponseEntity<>(cabinetService.queryChemicalsList(criteria, pageable), HttpStatus.OK);
    }

    @ApiOperation("化学品柜列表")
    @GetMapping("/poisonList")
    public ResponseEntity<Object> queryPoisonList(CabinetQueryCriteria criteria, Pageable pageable) {
        return new ResponseEntity<>(cabinetService.queryPoisonList(criteria, pageable), HttpStatus.OK);
    }

    @PostMapping("/openDoor")
    @ApiOperation("开门")
    @AnonymousAccess
    public ResponseEntity<Object> openDoor(Integer id) {
        cabinetService.openDoor(id);
        return new ResponseEntity<>("开门成功", HttpStatus.OK);
    }

    //给移动端使用，控制板开柜门
    @PostMapping("/openDoor-v2")
    @ApiOperation("开门")
    @Log("移动端开门")
    public ResponseEntity<Object> openDoorV2(Integer id) {
        System.out.println("开门:  " + id);
        try {
            cabinetService.openDoor(id);
            return new ResponseEntity<>(new BaseResult(0, "开门成功"), HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<>(new BaseResult(-1, e.getMessage()), HttpStatus.OK);
        }
    }


    @PostMapping("/closeDoor")
    @ApiOperation("关门")
    @Log("关门")
    public ResponseEntity<Object> closedoor(Integer id) {
        cabinetService.closeDoor(id);
        return new ResponseEntity<>("关门成功", HttpStatus.OK);
    }

    @GetMapping("/open")
    @AnonymousAccess
    @Log("开门")
    public ResponseEntity<Object> open(HttpServletRequest request) {
        Enumeration<String> headers = request.getHeaderNames();
        while (headers.hasMoreElements()) {
            String headName = headers.nextElement();
            if (Objects.equals(headName, "mac")) {
//                LogUtils.writeToFile("mac: "+headName+": "+request.getHeader(headName));
                return new ResponseEntity<>(cabinetService.open(request.getHeader(headName)), HttpStatus.OK);
            }
        }
//        LogUtils.writeToFile("open: return null");
        return new ResponseEntity<>(0, HttpStatus.OK);
    }

//    @GetMapping("/open")
//    @Log("开门")
//    @AnonymousAccess
//    public ResponseEntity<Object> open(String id) {
//        if (Objects.nonNull(id)) {
//            id = id.replace("[","").replace("]","");
//            Cabinet cabinet = cabinetRepository.getById(Integer.parseInt(id));
//            return new ResponseEntity<>(cabinet.getIsOpen(), HttpStatus.OK);
//        }
//        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
//    }

    //继电器开门
    @GetMapping("/open21")
    @AnonymousAccess
    public ResponseEntity<Object> open21(String id) {
        try {
            id = id.replace("[", "").replace("]", "");
            Cabinet cabinet = cabinetRepository.getById(Integer.parseInt(id));
            cabinet.setIsOpen(1);
            cabinet = cabinetRepository.save(cabinet);
            return new ResponseEntity<>(new BaseResult(0, "开门成功"), HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<>(new BaseResult(-1, e.getMessage()), HttpStatus.OK);
        }
    }

    @GetMapping("/hcList")
    @AnonymousAccess
    @ApiOperation("柜内物品")
    public ResponseEntity<Object> hcList(Integer id) {
        return new ResponseEntity<>(cabinetService.hcList(id), HttpStatus.OK);
    }

    @GetMapping("/queryCabinetsByLabId")
    @AnonymousAccess
    @ApiOperation("根据实验室查询化学品柜")
    public ResponseEntity<Object> queryCabinetsByLabId(Integer labId) {
        return new ResponseEntity<>(cabinetService.queryCabinetsByLabId(labId), HttpStatus.OK);
    }

    @GetMapping("/refrigeratorListPage")
    @ApiOperation("冰箱列表分页")
    public ResponseEntity<Object> refrigeratorListPage(CabinetQueryCriteria criteria, Pageable pageable) {
        return new ResponseEntity<>(cabinetService.refrigeratorListPage(criteria, pageable), HttpStatus.OK);
    }

    @GetMapping("/refrigeratorList")
    @ApiOperation("冰箱列表")
    public ResponseEntity<Object> refrigeratorList() {
        return new ResponseEntity<>(cabinetService.refrigeratorList(), HttpStatus.OK);
    }

    @GetMapping("/cabinetAllList")
    @ApiOperation("全部柜子列表")
    public ResponseEntity<Object> cabinetAllList() {
        return new ResponseEntity<>(cabinetService.cabinetAllList(), HttpStatus.OK);
    }

    @AnonymousGetMapping("/3d/getCountByFloor")
    @ApiOperation("楼层冰箱数量")
    public ResponseEntity<Object> getCountByFloor() {
        return new ResponseEntity<>(cabinetService.getCountByFloor(), HttpStatus.OK);
    }

    @AnonymousGetMapping("/3d/getRefrigeratorListByFloor")
    @ApiOperation("根据楼层获取冰箱列表")
    public ResponseEntity<Object> getRefrigeratorListByFloor(Integer floor) {
        return new ResponseEntity<>(cabinetService.getRefrigeratorListByFloor(floor), HttpStatus.OK);
    }

    @PostMapping("/setData")
    @ApiOperation("接收传感器数据")
    @AnonymousAccess
    public ResponseEntity<Object> setData(@RequestBody Map<String, String> map, HttpServletRequest request) {
        String ip = StringUtils.getIp(request);

        String devicesString = map.get("devices");

//        LogUtils.writeToFile("收到数据: " + ip + " " + devicesString);

        //去掉中括号
        devicesString = devicesString.replaceAll("^\\[|\\]$", "");
        devicesString = devicesString.replace("\"", "");

        if (StringUtils.isEmpty(devicesString)) {
            return new ResponseEntity<>(HttpStatus.OK);
        }

        LogUtils.writeToFile("处理数据: " + ip + " " + devicesString);

        String[] devices = devicesString.split(",");
        int i = 0;
        int total = devices.length;
        for (String device : devices) {
            if (device.length() < 10) {
                continue;
            }

            i += 1;
            LogUtils.writeToFile("处理中: " + i + "/" + total + " " + device);

            String mac = device.substring(2, 14);

//            LogUtils.writeToFile(" " + ip + " " + mac + " " + device + " " + device.length());

            int index = device.indexOf(mac);
            String data = device.substring(index, index + 76);
            String temperatureStr = data.substring(64, 68);//温度
            String humidityStr = data.substring(68, 72);//湿度
            int t_data = Integer.parseInt(temperatureStr, 16);
            int h_data = Integer.parseInt(humidityStr, 16);
            Float temperature = t_data / 65535f * 175 - 45;
            Float humidity = h_data / 65535f;

            DecimalFormat df = new DecimalFormat("#.0");

            LogUtils.writeToFile("setData: " + mac.toUpperCase() + " " + Float.parseFloat(df.format(temperature)) + " " + Float.parseFloat(df.format(humidity)));
            if (!cabinetService.setData(mac.toUpperCase(), Float.parseFloat(df.format(temperature)), Float.parseFloat(df.format(humidity)))) {
                incubatorService.setData(mac.toUpperCase(), Float.parseFloat(df.format(temperature)), Float.parseFloat(df.format(humidity)));
            }

        }

        return new ResponseEntity<>(HttpStatus.OK);
    }
}
